package com.sinaapp.gavinzhang.GSpider.plugin.batchprocessing;

import com.sinaapp.gavinzhang.GSpider.core.AbstractPageProcessor;
import com.sinaapp.gavinzhang.GSpider.webaddress.WebUrlCollection;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;



public class GSpiderHelper {
	private static Class<?> Gspider;
	private static Object o;
	private static Method setLogProperties;
	private static Method setListP;
	private static Method addWebUrl;
	private static Method init;
	private static Method start;
	private static Method getFoundWebUrlList;
	private static Method stop;
	private static Method look;
	private static Method getActiveCount;
	private static Method getCurrentUrlCount;
	private static Method setFindDestination;
	private static Method setCurrentWebUrlList;
	private static Method setFoundWebUrlList;
	private static Method check;
	private static boolean isLoad = false;
	
	public List<SpiderTask> spiderTasks;
	public List<SpiderTask> spiderdTasks;
	

	
	public GSpiderHelper() {
		System.out.println("GspiderHelper construct");
		spiderTasks = new ArrayList<SpiderTask>();
		spiderdTasks = new ArrayList<SpiderTask>();
	}
	public void init()
	{
		if(isLoad)
		{
			return;
		}
		else{
			isLoad = true;
		}
		try {
			Gspider = Class.forName("com.sinaapp.gavinzhang.GSpider.GSpider");
			setLogProperties = Gspider.getMethod("setLogProperties", String.class);
			setListP = Gspider.getMethod("setListP", List.class);
			addWebUrl = Gspider.getMethod("addWebUrl", String.class);
			init =Gspider.getMethod("init");
			start = Gspider.getMethod("start");
			getFoundWebUrlList = Gspider.getMethod("getFoundWebUrlList");
			stop = Gspider.getMethod("stop");
			look = Gspider.getMethod("look");
			getActiveCount = Gspider.getMethod("getActiveCount");
			getCurrentUrlCount = Gspider.getMethod("getCurrentUrlCount");
			setFindDestination = Gspider.getMethod("setFindDestination", AbstractPageProcessor.class);
			setCurrentWebUrlList = Gspider.getMethod("setCurrentWebUrlList", WebUrlCollection.class);
			setFoundWebUrlList = Gspider.getMethod("setFoundWebUrlList", WebUrlCollection.class);
			check = Gspider.getMethod("check");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void start()
	{
		if(spiderTasks==null || spiderTasks.size()==0)
		{
			System.err.println("SpiderTask is null");
			System.exit(-1);
		}
		try {
			o = Gspider.newInstance();
			setLogProperties.invoke(o, "log4j.properties");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		for(SpiderTask st : spiderTasks)
		{
			if(st.isFindFlag())continue;
			try {
				//设置爬取规则
				setListP.invoke(o, st.getListP());
				//加入待爬网址
				for(String s : st.getUrlList())
				{
					addWebUrl.invoke(o, s);
				}
				//设置目标处理函数
				if(st.getFindDestination() != null)
				{
					setFindDestination.invoke(o, st.getFindDestination());
				}
				//初始化系统
				init.invoke(o);
				//检查错误信息
				check.invoke(o);
				//开始任务
				start.invoke(o);
				Thread.sleep(1000);
				/*while(fList.size()<100)
				{
					//look.invoke(o);
					Thread.sleep(100);
				}
				//Thread.sleep(1000);*/
				while(!isFinish((Integer)getActiveCount.invoke(o), (Long)getCurrentUrlCount.invoke(o)))
				{
					Thread.sleep(100);
				}
				
				
				stop.invoke(o);
				//setTaskExecutor.invoke(o);
				
			} catch (Exception  e) {
				e.printStackTrace();
			}
		}
		
		
	}
	
	public static GSpiderHelper createGspiderHelperByXml(String xml)
	{
		return createGspiderHelperByXml(new File(xml));
	}
	
	public static GSpiderHelper createGspiderHelperByXml(File f)
	{
		GSpiderHelper g = new GSpiderHelper();
		SAXReader reader = new SAXReader();
		    try {
				Document xml = reader.read(f);
				Element root = xml.getRootElement();
				if(!root.getName().equals("Gspider-config"))return null;
				Element log = root.element("log");
				String logfile = log.elementText("logfile");
				List<Element> spidertasks = root.element("spider-tasks").elements();
				SpiderTask spiderTask;
				List<String> urlList;
				List<Pattern> listP;
				for(Element e : spidertasks)
				{
					spiderTask = new SpiderTask();
					if(!e.getName().equals("spider-task")){return null;}
					List<Element> urllist = e.element("url-list").elements();
					List<Element> patternlist = e.element("pattern-list").elements();
					String findDestination = e.elementText("findDestination");
					String findFlag = e.elementText("findFlag");
					urlList = new ArrayList<String>();
					for(Element url : urllist)
					{
						urlList.add((String)url.getData());
					}
					listP = new ArrayList<Pattern>();
					Pattern p;
					for(Element pattern : patternlist)
					{
						p = Pattern.compile((String)pattern.getData());
						listP.add(p);
					}
					if(findDestination != null)
					{
						spiderTask.setFindDestination((AbstractPageProcessor) Class.forName("findDestination").newInstance());
					}
					if(findFlag != null)
					{
						spiderTask.setFindFlag(Boolean.valueOf(findFlag));
					}
					String attrName = null;
					String name = null;
					name=(e.elementText("name")==null)?null:e.elementText("name");
					attrName = (e.attributeValue("name")==null)?null:e.attributeValue("name");
					if(attrName==null&&name==null)throw new DocumentException();
					if((attrName!=null&&name!=null) && !name.equals(attrName))throw new DocumentException();
					if(name==null)name=attrName;
					spiderTask.setName(name);
					spiderTask.setListP(listP);
					spiderTask.setUrlList(urlList);
					g.spiderTasks.add(spiderTask);
				}
				g.init();
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		    return g;
	}
	


	public static boolean isFinish(int ActiveCount,long CurrentUrlCount)
	{
		if(ActiveCount==0 && CurrentUrlCount==0L)
		{
			return true;
		}
		return false;
	}
	public static void main(String[] args)
	{
		GSpiderHelper g = createGspiderHelperByXml("src/main/resources/GspiderConfig.xml");
		g.start();
		//mulu();
	}

	public static void mulu()
	{
		System.out.println("Java运行时环境版本:\n"+System.getProperty("java.version"));

		System.out.println("Java 运行时环境供应商:\n"+System.getProperty("java.vendor"));

		System.out.println("Java 供应商的URL:\n"+System.getProperty("java.vendor.url"));

		System.out.println("Java安装目录:\n"+System.getProperty("java.home"));

		System.out.println("Java 虚拟机规范版本:\n"+System.getProperty("java.vm.specification.version"));

		System.out.println("Java 类格式版本号:\n"+System.getProperty("java.class.version"));

		System.out.println("Java类路径：\n"+System.getProperty("java.class.path"));

		System.out.println("加载库时搜索的路径列表:\n"+System.getProperty("java.library.path"));

		System.out.println("默认的临时文件路径:\n"+System.getProperty("java.io.tmpdir"));

		System.out.println("要使用的 JIT 编译器的名称:\n"+System.getProperty("java.compiler"));

		System.out.println("一个或多个扩展目录的路径:\n"+System.getProperty("java.ext.dirs"));

		System.out.println("操作系统的名称:\n"+System.getProperty("os.name"));

		System.out.println("操作系统的架构:\n"+System.getProperty("os.arch"));

		System.out.println("操作系统的版本:\n"+System.getProperty("os.version"));

		System.out.println("文件分隔符（在 UNIX 系统中是“/”）:\n"+System.getProperty("file.separator"));

		System.out.println("路径分隔符（在 UNIX 系统中是“:”）:\n"+System.getProperty("path.separator"));

		System.out.println("行分隔符（在 UNIX 系统中是“/n”）:\n"+System.getProperty("line.separator"));

		System.out.println("用户的账户名称:\n"+System.getProperty("user.name"));

		System.out.println("用户的主目录:\n"+System.getProperty("user.home"));

		System.out.println("用户的当前工作目录:\n"+System.getProperty("user.dir"));
	}

}
